## Shannon's channel rate versus bandwidth

from PyM import *

# L = log2


def shannon_rate(w): return w * L(1+1/w)

# upper limit of the Shannon's rate
ym = L(exp(1))

# Important points
def X(k): return (k,0)
def Y(k): return (0,k)

# Convinient steps for the axis
dx = 1; dy = 0.05

# Range of the normalized bandwidth; 
# starts at 0.001 to avoid divisin by 0
w = ls(0.001,33,300)

# plotting
close('all')

# Canvas
ax = plt.figure("Shannon's channel rate", figsize=(6,6))
plt.xlim(-6*dx,40)
plt.ylim(-2*dy,1.5)

plt.axis('off')

# Ticking utilities ticks on axes
def vtick(x,l=0.01):
    return seg((x,-l),(x,l))
def htick(y,l=0.01):
    return seg((-l,y),(l,y))

# Axes    
ruler(X(0),X(30))
ruler(Y(0),Y(1.4))

# Ticking the axis
for a in range(5,31,5):
    vtick(a,0.02)
for b in range(2,15,2):
    htick(b/10,0.4)

# Lables
for j in range(10,31,5):
    lable(X(j),str(j),dx=-1.2*dx,dy=-2*dy)
#
lable(X(5),str(5),dx=-0.5*dx,dy=-2*dy)

for j in range(2,15,2):
    lable(Y(j/10),str(j/10),dx=-5*dx,dy=-0.5*dy)

lable(X(34),r'$W$',dy=-0.5*dy)

# Dashed segments
seg(Y(ym),(33,ym),dashing='--')

# Draw Shannon's rate curve
plot(w, shannon_rate(w),color='blue')
    
plt.show()